Xceed Encryption Library Documentation
Examples / Combine encryption and compression





In This Topic
Combine encryption and compression
In This Topic

Here are is an example for Visual C++ and C# that demonstrates combining encryption and compression entirely in memory in a single pass. It shows how to use the Rijndael algorithm and the GZip compression format to encrypt compressed data and, then reverse the process.

// This code uses the #import directive. The components don't have a DLL-API.

// Import the COM interface of Xceed Encryption for COM/ActiveX
#import "XceedCry.dll" no_namespace named_guids

/* Both Xceed Encryption for COM/ActiveX and Xceed Streaming Compression for COM/ActiveX
   component define an interface called IXceedProcessData that allow the components to
   exchange data. When using both components at the same time, this will cause a naming
   conflict with the compiler. To solve, that, we will instruct the second component
   that is imported to exclude the interface to avoid the conflict. */

// Import the COM interface of Xceed Streaming Compression for COM/ActiveX
#import "XceedSco.dll" no_namespace named_guids exclude("IXceedProcessData")

void CompressEncrypt1()
{
  CoInitialize( NULL ); 

  try
  {
    // Create and license a streaming compression control object
    IXceedStreamingCompressionPtr compression;
    compression.CreateInstance( CLSID_XceedStreamingCompression );
    compression->License( _bstr_t( YourStreamingCompressionLicenseKey ) );
    
    // Create and setup a GZip compression object
    IXceedGZipCompressionFormatPtr gzip;
    gzip.CreateInstance( CLSID_XceedGZipCompressionFormat );

    // Create and license an encryption control object
    IXceedEncryptionPtr encryption; 
    encryption.CreateInstance( CLSID_XceedEncryption ); 
    encryption->License( _bstr_t( YourEncryptionLicenseKey ) ); 

    // Create and setup a rijndael (AES) encryption object
    IXceedRijndaelEncryptionMethodPtr rijndael; 
    rijndael.CreateInstance( CLSID_XceedRijndaelEncryptionMethod );  
    rijndael->SetSecretKeyFromPassPhrase( "This is a weak pass phrase!", 128 ); 
    
    /* Order is important. We want to compress data before we encrypt it. So we will assign
       the compression as a sub processor to the encryption. This will have the effect that the
       encryption will ask the compression object to process the data BEFORE it encrypts. */

    // Link the encryption object with the compression object
    rijndael->SubProcessing = IXceedProcessDataPtr( gzip );

    // Assign the encryption object to the encryption control so we can perform operations on it
    encryption->EncryptionMethod = IXceedEncryptDataPtr( rijndael );  

    // Set up data to compress/encrypt
    const char * pszSource = "This is the data to encrypt"; 
    DWORD dwSourceSize = lstrlenA( pszSource ) + 1; // Let's say we want to encrypt the null-char too 
    
    // Setup variables to receive the encrypted data
    BYTE * pcEncrypted = NULL;
    DWORD dwEncryptedSize = 0;

    // Compress/encrypt the data
    encryption->Encrypt( ( BYTE* ) pszSource, dwSourceSize, TRUE, &pcEncrypted, &dwEncryptedSize );  

    /* TODO: Store the encrypted data somewhere */
    BYTE * dataStore = new BYTE[ dwEncryptedSize ];
    memcpy( dataStore, pcEncrypted, dwEncryptedSize );

    // It is important to release the memory used by the encrypted data to avoid memory leaks
    CoTaskMemFree( pcEncrypted ); 

    /* .... */

    /* To decrypt/decompress, we setup the objects exactly like you would for compression/encryption.
       But we will use the Decrypt() method instead. The method will perform SubProcessing by
       decrypting FIRST, and then sending the data for decompression. */

    // Setup variables to receive the decrypted data
    BYTE* pcDecrypted = NULL;
    DWORD dwDecryptedSize = 0;

    // Decrypt/decompress the data
    encryption->Decrypt( ( BYTE* ) dataStore, dwEncryptedSize, TRUE, &pcDecrypted, &dwDecryptedSize );  

    // Reconstitute the original data
    char * pszReconstitutedSource =  ( char * ) pcDecrypted; 

    // Release the memory used by the decrypted data
    CoTaskMemFree( pcDecrypted ); 

    // Release the data store memory we used
    delete[] dataStore;
  }
  catch( const _com_error& xErr )
  {
    WCHAR szMsg[50]; 
    wsprintf( szMsg, L"Error %08x\n", xErr.Error() ); 
    OutputDebugString( szMsg );
  }
  catch( ... )
  {
    OutputDebugString( L"Unknown error" );
  } 

  CoUninitialize();
}
See Also